package org.vison.wonfu.framework.soa.protocol.rest;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.net.URIBuilder;
import org.vison.wonfu.framework.soa.Invocation;
import org.vison.wonfu.framework.soa.annotation.SoaRequestMethod;
import org.vison.wonfu.framework.soa.exception.RpcException;
import org.vison.wonfu.framework.soa.protocol.AbstractParamsHandler;
import org.vison.wonfu.framework.soa.protocol.InvocationParamsHandler;
import org.vison.wonfu.framework.soa.protocol.Protocol;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;

@InvocationParamsHandler(protocol = Protocol.REST)
public class RestParamsHandler extends AbstractParamsHandler {

    private static final ContentType CONTENT_TYPE = ContentType.create("application/json", StandardCharsets.UTF_8);

    @Override
    protected SimpleHttpRequest doPack(Invocation invocation, String uri, Object[] argument) throws RpcException {
        ObjectMapper objectMapper = getContextObjectMapper(invocation);
        // Rest协议 只有一个参数
        if (argument != null && argument.length > 1) {
            throw new RpcException(RpcException.SOA_DEFINITION, "Rest协议 只能定义一个参数");
        }
        // 获取请求方法类型
        SoaRequestMethod requestMethod = invocation.getSoaRequestMethod();
        SimpleRequestBuilder requestBuilder;

        switch (requestMethod) {
            case GET:
                URI uriObj;
                try {
                    if (argument != null) {
                        List<NameValuePair> pairs = buildNameValuePair(invocation,argument[0],objectMapper);
                        uriObj = new URIBuilder(uri).addParameters(pairs).build();
                    }else{
                        uriObj = new URI(uri);
                    }
                    requestBuilder = SimpleRequestBuilder.get(uriObj);
                } catch (URISyntaxException e) {
                    throw new RpcException(RpcException.SOA_DEFINITION, "Rest协议 GET请求参数格式错误", e);
                }

                break;
            case POST:
                requestBuilder = SimpleRequestBuilder.post(uri);
                // 序列化请求体
                if (argument != null) {
                    byte[] bodyBytes = writeValueAsBytes(objectMapper, argument[0]);
                    requestBuilder.setBody(bodyBytes, CONTENT_TYPE);
                }
                break;
            case PUT:
                requestBuilder = SimpleRequestBuilder.put(uri);
                    // 序列化请求体
                    if (argument != null) {
                        byte[] bodyBytes = writeValueAsBytes(objectMapper, argument[0]);
                        requestBuilder.setBody(bodyBytes, CONTENT_TYPE);
                    }
                break;
            case DELETE:
                requestBuilder = SimpleRequestBuilder.delete(uri);
                // DELETE请求通常也不设置请求体
                break;
            default:
                // 默认使用POST
                requestBuilder = SimpleRequestBuilder.post(uri);
                if (argument != null) {
                    // 序列化请求体
                    byte[] bodyBytes = writeValueAsBytes(objectMapper, argument[0]);
                    requestBuilder.setBody(bodyBytes, CONTENT_TYPE);
                }
                break;
        }

        return requestBuilder.build();
    }
}